home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianDrawings.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  50KB  |  1,792 lines

  1. /*ScianDrawings.c
  2.   Little drawing elements to put on space panels, etc.
  3.   Eric Pepke
  4.   March 3, 1992
  5. */
  6.  
  7. #include "Scian.h"
  8. #include "ScianTypes.h"
  9. #include "ScianLists.h"
  10. #include "ScianControls.h"
  11. #include "ScianButtons.h"
  12. #include "ScianColors.h"
  13. #include "ScianIDs.h"
  14. #include "ScianEvents.h"
  15. #include "ScianArrays.h"
  16. #include "ScianErrors.h"
  17. #include "ScianWindows.h"
  18. #include "ScianDraw.h"
  19. #include "ScianObjWindows.h"
  20. #include "ScianVisWindows.h"
  21. #include "ScianDialogs.h"
  22. #include "ScianSliders.h"
  23. #include "ScianTextBoxes.h"
  24. #include "ScianTitleBoxes.h"
  25. #include "ScianMethods.h"
  26. #include "ScianStyle.h"
  27. #include "ScianDrawings.h"
  28. #include "ScianScripts.h"
  29. #include "ScianPick.h"
  30. #include "ScianTemplates.h"
  31. #include "ScianTemplateHelper.h"
  32. #include "ScianSymbols.h"
  33. #include "ScianScales.h"
  34.  
  35. ObjPtr drawingClass, rectangleClass, lineClass;
  36.  
  37. int nAnnot = 1;
  38. int nRect = 1;
  39. int nLine = 1;
  40. int nTimeReadout = 1;
  41.  
  42. ObjPtr DeleteSpacePanelDrawing(drawing)
  43. ObjPtr drawing;
  44. /*Additional stuff to do when deleting a drawing from a space panel*/
  45. {
  46.     return ObjTrue;
  47. }
  48.  
  49. ObjPtr DuplicateDrawing(object)
  50. ObjPtr object;
  51. /*Duplicates a drawing*/
  52. {
  53.     ObjPtr parent, contents;
  54.     FuncTyp method;
  55.  
  56.     parent = GetVar(object, PARENT);
  57.     if (!parent)
  58.     {
  59.     ReportError("DuplicateDrawing", "Cannot find parent of drawing");
  60.     return ObjFalse;
  61.     }
  62.  
  63.     contents = GetListVar("DuplicateDrawing", parent, CONTENTS);
  64.     if (!contents)
  65.     {
  66.     return ObjFalse;
  67.     }
  68.  
  69.     method = GetMethodSurely("DuplicateDrawing", object, CLONE);
  70.     if (!method)
  71.     {
  72.     return ObjFalse;
  73.     }
  74.  
  75.     object = (*method)(object);
  76.     if (object)
  77.     {
  78.     ObjPtr var;
  79.     real bounds[4], loc[2];
  80.  
  81.     /*Change bounds, if any*/
  82.     var = GetVar(object, BOUNDS);
  83.     if (var && IsRealArray(var) && RANK(var) == 1 && DIMS(var)[0] == 4)
  84.     {
  85.         Array2CArray(bounds, var);
  86.         bounds[0] += DUPOFFSET;
  87.         bounds[1] += DUPOFFSET;
  88.         bounds[2] -= DUPOFFSET;
  89.         bounds[3] -= DUPOFFSET;
  90.         var = NewRealArray(1, 4L);
  91.         CArray2Array(var, bounds);
  92.         SetVar(object, BOUNDS, var);
  93.     }
  94.  
  95.     /*Change startpoint, if any*/
  96.     var = GetVar(object, STARTPOINT);
  97.     if (var && IsRealArray(var) && RANK(var) == 1 && DIMS(var)[0] == 2)
  98.     {
  99.         Array2CArray(loc, var);
  100.         loc[0] += DUPOFFSET;
  101.         loc[1] -= DUPOFFSET;
  102.         var = NewRealArray(1, 2L);
  103.         CArray2Array(var, loc);
  104.         SetVar(object, STARTPOINT, var);
  105.     }
  106.  
  107.     /*Change endpoint, if any*/
  108.     var = GetVar(object, ENDPOINT);
  109.     if (var && IsRealArray(var) && RANK(var) == 1 && DIMS(var)[0] == 2)
  110.     {
  111.         Array2CArray(loc, var);
  112.         loc[0] += DUPOFFSET;
  113.         loc[1] -= DUPOFFSET;
  114.         var = NewRealArray(1, 2L);
  115.         CArray2Array(var, loc);
  116.         SetVar(object, ENDPOINT, var);
  117.     }
  118.  
  119.     /*Unselect it, kludge*/
  120.     SetVar(object, SELECTED, ObjFalse);
  121.  
  122.     PrefixList(contents, object);
  123.     SetVar(object, PARENT, parent);
  124.     ImInvalid(object);
  125.     }
  126.     return ObjTrue;
  127. }
  128.  
  129. static ObjPtr SelectDrawing(object, selectp)
  130. ObjPtr object;
  131. Bool selectp;
  132. /*Selects a drawing*/
  133. {
  134.     Bool alreadySelected;
  135.  
  136.     alreadySelected = IsSelected(object);
  137.     if (selectp == alreadySelected)
  138.     {
  139.     return ObjTrue;
  140.     }
  141.  
  142.     ImInvalid(object);
  143.  
  144.     return ObjTrue;
  145. }
  146.  
  147. #ifdef PROTO
  148. ObjPtr NewRectangle(int l, int r, int b, int t, char *name)
  149. #else
  150. ObjPtr NewRectangle(l, r, b, t, name)
  151. int l; int r; int b; int t; char *name;
  152. #endif
  153. {
  154.     ObjPtr retVal;
  155.  
  156.     retVal = NewObject(rectangleClass, 0L);
  157.     Set2DIntBounds(retVal, l, r, b, t);
  158.     SetVar(retVal, NAME, NewString(name));
  159.     SetMethod(retVal, CLONE, CloneRectangle);
  160.  
  161.     return retVal;
  162. }
  163.  
  164. #ifdef PROTO
  165. ObjPtr NewLine(int x1, int y1, int x2, int y2, char *name)
  166. #else
  167. ObjPtr NewLine(x1, y1, x2, y2, name)
  168. int x1; int y1; int x2; int y2; char *name;
  169. #endif
  170. {
  171.     ObjPtr retVal;
  172.     int l, r, b, t;
  173.     real loc[2];
  174.     ObjPtr var;
  175.  
  176.     l = MIN(x1, x2) - HANDLESIZE / 2;
  177.     r = MAX(x1, x2) + HANDLESIZE / 2;
  178.     b = MIN(y1, y2) - HANDLESIZE / 2;
  179.     t = MAX(y1, y2) + HANDLESIZE / 2;
  180.     retVal = NewObject(lineClass, 0L);
  181.     Set2DIntBounds(retVal, l, r, b, t);
  182.     SetVar(retVal, NAME, NewString(name));
  183.     SetMethod(retVal, CLONE, CloneLine);
  184.  
  185.     var = NewRealArray(1, 2L);
  186.     loc[0] = x1;
  187.     loc[1] = y1;
  188.     CArray2Array(var, loc);
  189.     SetVar(retVal, STARTPOINT, var);
  190.  
  191.     var = NewRealArray(1, 2L);
  192.     loc[0] = x2;
  193.     loc[1] = y2;
  194.     CArray2Array(var, loc);
  195.     SetVar(retVal, ENDPOINT, var);
  196.  
  197.     return retVal;
  198. }
  199.  
  200. static ObjPtr PressRectangle(rectangle, x, y, flags)
  201. ObjPtr rectangle;
  202. int x, y;
  203. long flags;
  204. {
  205. #ifdef INTERACTIVE
  206.     ObjPtr var, retVal = ObjFalse;
  207.     int left, right, bottom, top, hCent, vCent;
  208.     Bool ml, mr, mb, mt;
  209.  
  210.     Get2DIntBounds(rectangle, &left, &right, &bottom, &top);
  211.  
  212.     if (x >= left && x <= right && y >= bottom && y <= top)
  213.     {
  214.     if (TOOL(flags) == T_HELP)
  215.     {
  216.         ContextHelp(rectangle);
  217.         return ObjTrue;
  218.     }
  219.  
  220.     /* return if not active */
  221.     if (!GetPredicate(rectangle, ACTIVATED)) return ObjFalse;
  222.  
  223.     hCent = (left + right)/2;
  224.     vCent = (bottom + top)/2;
  225.  
  226.     MakeMeCurrent(rectangle);
  227.  
  228.     ml = mr = mb = mt = false;
  229.  
  230.     if (x < left + HANDLESIZE) /* on left side */
  231.     {
  232.         if (y > top - HANDLESIZE) /* top-left handle */
  233.         mt = ml = true;
  234.         else if (y < bottom + HANDLESIZE) /* bottom-left handle */
  235.         mb = ml = true;
  236.         else if (y > vCent - HANDLESIZE/2 && y < vCent + HANDLESIZE/2)
  237.         ml = true; /* bottom middle handle */
  238.         else ml = mr = mb = mt = true; /* in frame */
  239.     }
  240.     else if (x > right - HANDLESIZE) /* on right side */
  241.     {
  242.         if (y > top - HANDLESIZE) /* top-right handle */
  243.         mt = mr = true;
  244.         else if (y < bottom + HANDLESIZE) /* bottom-right handle */
  245.         mb = mr = true;
  246.         else if (y > vCent - HANDLESIZE/2 && y < vCent + HANDLESIZE/2)
  247.         mr = true;
  248.         else ml = mr = mb = mt = true; /* in frame */
  249.     }
  250.     else if (y < bottom + HANDLESIZE) /* on bottom */
  251.     {
  252.         /* already handled (heh heh) corners */
  253.         if (x > hCent - HANDLESIZE/2 && x < hCent + HANDLESIZE/2)
  254.         mb = true; /* bottom middle handle */
  255.         else ml = mr = mb = mt = true; /* in frame */
  256.     }
  257.     else if (y > top - HANDLESIZE) /* on top */
  258.     {
  259.         /* already handled (heh heh) corners */
  260.         if (x > hCent - HANDLESIZE/2 && x < hCent + HANDLESIZE/2)
  261.         mt = true; /* middle top handle */
  262.         else ml = mr = mb = mt = true; /* in frame */
  263.     }
  264.  
  265.     if (mr || ml || mb || mt || GetVar(rectangle, BACKGROUND))
  266.     {
  267.         if (!(flags & F_EXTEND) && !IsSelected(rectangle))
  268.         {
  269.         /*It's a new selection and not already selected.  Deselect the
  270.           rest*/
  271.         DeselectAll();
  272.         }
  273.  
  274.         if ((flags & F_EXTEND) && IsSelected(rectangle))
  275.         {
  276.         /*Deselect*/
  277.         Select(rectangle, false);
  278.         return ObjTrue;
  279.         }
  280.         else if (!IsSelected(rectangle))
  281.         {
  282.         /*Must select it*/
  283.         
  284.         Select(rectangle, true);
  285.         DrawMe(rectangle);
  286.         UpdateDrawing();
  287.         retVal = ObjTrue;
  288.         }
  289.     }
  290.  
  291.     if (mr || ml || mb || mt) /* drag the incredibly fancy frame around */
  292.     {
  293.         /* I am greatly indebted to my friend and colleague, Eric Pepke,
  294.            for the following code. Any errors or obfuscations are his. 
  295.            Since I stole this back from Jim, the errors are now his.*/
  296.         int initX = x, initY = y;
  297.         int mX, mY;
  298.         int newLeft, newRight, newBottom, newTop;
  299.         int oldNewLeft, oldNewRight, oldNewBottom, oldNewTop;
  300.  
  301.         SaveForUndo(rectangle);
  302.  
  303.         newLeft = oldNewLeft = left;
  304.         newRight = oldNewRight = right;
  305.         newBottom = oldNewBottom = bottom;
  306.         newTop = oldNewTop = top;
  307.  
  308.         while (Mouse(&mX, &mY) && (mX == initX) && (mY == initY));
  309.  
  310.         DrawSkeleton(true);
  311.         while (Mouse(&mX, &mY))
  312.         {
  313.         if (ml) newLeft = left + mX - initX;
  314.         if (mr) newRight = right + mX - initX;
  315.         if (mb) newBottom = bottom + mY - initY;
  316.         if (mt) newTop = top + mY - initY;
  317.  
  318.         if (flags & F_SHIFTDOWN)
  319.         {
  320.             /*Grid drag*/
  321.             if (ml && mr && mb && mt)
  322.             {
  323.             /*Special case--whole object gridded
  324.                 Only grid top left*/
  325.             int width, height;
  326.             width = newRight - newLeft;
  327.             height = newTop - newBottom;
  328.             newLeft = GRIDX(newLeft);
  329.             newRight = newLeft + width;
  330.             newTop = top - (GRIDY(top - newTop));
  331.             newBottom = newTop - height;
  332.             }
  333.             else
  334.             {
  335.             /*Normal case*/
  336.             if (ml) newLeft = GRIDX(newLeft);
  337.             if (mr) newRight = right - GRIDX(right - newRight);
  338.             if (mb) newBottom = GRIDY(newBottom);
  339.             if (mt) newTop = top - GRIDY(top - newTop);
  340.             }
  341.         }
  342.         if (ml && newLeft + 3 * HANDLESIZE > newRight)
  343.                 newLeft = newRight - 3 * HANDLESIZE;
  344.         if (mr && newLeft + 3 * HANDLESIZE > newRight)
  345.                 newRight = newLeft + 3 * HANDLESIZE;
  346.         if (mb && newBottom + 3 * HANDLESIZE > newTop)
  347.                 newBottom = newTop - 3 * HANDLESIZE;
  348.         if (mt && newBottom + 3 * HANDLESIZE > newTop)
  349.                 newTop = newBottom + 3 * HANDLESIZE;
  350.         if ((newLeft != oldNewLeft ||
  351.                 newRight != oldNewRight ||
  352.                 newBottom != oldNewBottom ||
  353.                 newTop != oldNewTop) &&
  354.                 newLeft < newRight &&
  355.                 newBottom < newTop)
  356.         {
  357.             Set2DIntBounds(rectangle,
  358.                    newLeft, newRight, newBottom, newTop);
  359.             oldNewLeft = newLeft;
  360.             oldNewRight = newRight;
  361.             oldNewBottom = newBottom;
  362.             oldNewTop = newTop;
  363.  
  364.             DrawMe(rectangle);
  365.         }
  366.         }
  367.  
  368.         DrawSkeleton(false);
  369.  
  370.         if (logging)
  371.         {
  372.         char cmd[256];
  373.         MakeObjectName(tempStr, rectangle);
  374.         sprintf(cmd, "set bounds %s [%d %d %d %d]\n",
  375.             tempStr, newLeft, newRight,
  376.             newBottom, newTop);
  377.         Log(cmd);
  378.         }
  379.         retVal = ObjTrue;
  380.     }
  381.     else if (GetVar(rectangle, BACKGROUND))
  382.     {
  383.         retVal = ObjTrue;
  384.     }
  385.  
  386.     return retVal;
  387.     }
  388. #endif
  389.     return ObjFalse;
  390. }
  391.  
  392. static ObjPtr PressLine(line, x, y, flags)
  393. ObjPtr line;
  394. int x, y;
  395. long flags;
  396. /*Presses in a line*/
  397. {
  398. #ifdef INTERACTIVE
  399.     ObjPtr var;
  400.     int left, right, bottom, top;
  401.     Bool inLine = false;
  402.  
  403.     Get2DIntBounds(line, &left, &right, &bottom, &top);
  404.  
  405.     if (x >= left && x <= right && y >= bottom && y <= top)
  406.     {
  407.     real startPoint[2], endPoint[2];
  408.     real xDisp[2], yDisp[2];
  409.     real resultX, resultY;
  410.     int startX, startY, newX, newY;
  411.     ObjPtr pickedObjects;
  412.     Bool justSelected = false;
  413.  
  414.     if (TOOL(flags) == T_HELP)
  415.     {
  416.         ContextHelp(line);
  417.         return ObjTrue;
  418.     }
  419.  
  420.     /* return if not active */
  421.     if (!GetPredicate(line, ACTIVATED)) return ObjFalse;
  422.  
  423.     /*See if we picked the line*/
  424.     SetOrthoPick();
  425.     StartPick();
  426.     MakeOrthoXform();
  427.  
  428.     PickObject(line, PR_CENTER);
  429. #ifdef GRAPHICS
  430.     DrawObject(line);
  431. #endif
  432.     EndPickObject(line);
  433.     pickedObjects = StopPick();
  434.     RestoreOrthoPick();
  435.  
  436.     if (pickedObjects)
  437.     {
  438.         inLine = true;
  439.  
  440.         if ((!(flags & F_EXTEND)) && !IsSelected(line))
  441.         {
  442.         /*It's a new selection and not already selected.  Deselect the
  443.           rest*/
  444.         DeselectAll();
  445.         }
  446.  
  447.         if ((flags & F_EXTEND) && IsSelected(line))
  448.         {
  449.         /*Deselect*/
  450.         Select(line, false);
  451.         }
  452.         else if (!IsSelected(line))
  453.         {
  454.         /*Must select it*/
  455.         MakeMeCurrent(line);
  456.         Select(line, true);
  457.         DrawMe(line);
  458.         UpdateDrawing();
  459.         justSelected = true;
  460.         }
  461.     }
  462.  
  463.     if (IsSelected(line))
  464.     {
  465.         /*See if we're in either of the endpoints*/
  466.         var = GetFixedArrayVar("PressLine", line, STARTPOINT, 1, 2L);
  467.         Array2CArray(startPoint, var);
  468.  
  469.         var = GetFixedArrayVar("PressLine", line, ENDPOINT, 1, 2L);
  470.         Array2CArray(endPoint, var);
  471.  
  472.         if (justSelected)
  473.         {
  474.         while(Mouse(&newX, &newY) &&
  475.             newX == x && newY == y);
  476.         }
  477.  
  478.         /*Click in startPoint?*/
  479.         if (x >= startPoint[0] - HANDLESIZE / 2 && 
  480.         x <= startPoint[0] + HANDLESIZE / 2 &&
  481.         y >= startPoint[1] - HANDLESIZE / 2 &&
  482.         y <= startPoint[1] + HANDLESIZE / 2)
  483.         {
  484.         SaveForUndo(line);
  485.         startX = x;
  486.         startY = y;
  487.         xDisp[0] = x - startPoint[0];
  488.         yDisp[0] = y - startPoint[1];
  489.  
  490.         DrawSkeleton(true);
  491.  
  492.         while (Mouse(&newX, &newY))
  493.         {
  494.             resultX = newX - xDisp[0];
  495.             resultY = newY - yDisp[0];
  496.             if (flags & F_SHIFTDOWN)
  497.             {
  498.             resultX = GRIDX(resultX);
  499.             resultY = GRIDY(resultY);
  500.             }
  501.  
  502.             if (resultX != startPoint[0] || resultY != startPoint[1])
  503.             {
  504.             startPoint[0] = resultX;
  505.             startPoint[1] = resultY;
  506.             var = NewRealArray(1, 2L);
  507.             CArray2Array(var, startPoint);
  508.             SetVar(line, STARTPOINT, var);
  509.             Set2DIntBounds(line,
  510.                     MIN(startPoint[0], endPoint[0]) - HANDLESIZE / 2,
  511.                     MAX(startPoint[0], endPoint[0]) + HANDLESIZE / 2,
  512.                     MIN(startPoint[1], endPoint[1]) - HANDLESIZE / 2, 
  513.                     MAX(startPoint[1], endPoint[1]) + HANDLESIZE / 2);
  514.             DrawMe(line);
  515.             }
  516.         }
  517.  
  518.         DrawSkeleton(false);
  519.         inLine = true;
  520.         }
  521.         /*Click in endPoint?*/
  522.         else if (x >= endPoint[0] - HANDLESIZE / 2 && 
  523.         x <= endPoint[0] + HANDLESIZE / 2 &&
  524.         y >= endPoint[1] - HANDLESIZE / 2 &&
  525.         y <= endPoint[1] + HANDLESIZE / 2)
  526.         {
  527.         SaveForUndo(line);
  528.         startX = x;
  529.         startY = y;
  530.         xDisp[1] = x - endPoint[0];
  531.         yDisp[1] = y - endPoint[1];
  532.         DrawSkeleton(true);
  533.         while (Mouse(&newX, &newY))
  534.         {
  535.             resultX = newX - xDisp[1];
  536.             resultY = newY - yDisp[1];
  537.             if (flags & F_SHIFTDOWN)
  538.             {
  539.             resultX = GRIDX(resultX);
  540.             resultY = GRIDY(resultY);
  541.             }
  542.  
  543.             if (resultX != endPoint[0] || resultY != endPoint[1])
  544.             {
  545.             endPoint[0] = resultX;
  546.             endPoint[1] = resultY;
  547.             var = NewRealArray(1, 2L);
  548.             CArray2Array(var, endPoint);
  549.             SetVar(line, ENDPOINT, var);
  550.             Set2DIntBounds(line,
  551.                 MIN(startPoint[0], endPoint[0]) - HANDLESIZE / 2,
  552.                 MAX(startPoint[0], endPoint[0]) + HANDLESIZE / 2,
  553.                 MIN(startPoint[1], endPoint[1]) - HANDLESIZE / 2, 
  554.                 MAX(startPoint[1], endPoint[1]) + HANDLESIZE / 2);
  555.             DrawMe(line);
  556.             }
  557.         }
  558.         DrawSkeleton(false);
  559.         inLine = true;
  560.         }
  561.         else if (inLine)
  562.         {
  563.         /*Click on line.  Move but only grid deltas*/
  564.         real dx, dy;
  565.  
  566.         SaveForUndo(line);
  567.         startX = x;
  568.         startY = y;
  569.         DrawSkeleton(true);
  570.         while (Mouse(&newX, &newY))
  571.         {
  572.             dx = newX - x;
  573.             dy = newY - y;
  574.             if (flags & F_SHIFTDOWN)
  575.             {
  576.             dx = DGX(dx);
  577.             dy = DGY(dy);
  578.             }
  579.             if (dx != 0 || dy != 0)
  580.             {
  581.             x = newX;
  582.             y = newY;
  583.             startPoint[0] += dx;
  584.             startPoint[1] += dy;
  585.             var = NewRealArray(1, 2L);
  586.             CArray2Array(var, startPoint);
  587.             SetVar(line, STARTPOINT, var);
  588.  
  589.             endPoint[0] += dx;
  590.             endPoint[1] += dy;
  591.             var = NewRealArray(1, 2L);
  592.             CArray2Array(var, endPoint);
  593.             SetVar(line, ENDPOINT, var);
  594.  
  595.             Set2DIntBounds(line,
  596.                 MIN(startPoint[0], endPoint[0]) - HANDLESIZE / 2,
  597.                 MAX(startPoint[0], endPoint[0]) + HANDLESIZE / 2,
  598.                 MIN(startPoint[1], endPoint[1]) - HANDLESIZE / 2, 
  599.                 MAX(startPoint[1], endPoint[1]) + HANDLESIZE / 2);
  600.             DrawMe(line);
  601.             }
  602.         }
  603.         DrawSkeleton(false);
  604.         }
  605.         else
  606.         {
  607.         inLine = false;
  608.         }
  609.         if (inLine)
  610.         if (logging)
  611.         {
  612.         char cmd[256];
  613.         MakeObjectName(tempStr, line);
  614.         sprintf(cmd, "set endpoints %s %g %g %g %g\n",
  615.             tempStr, startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
  616.         Log(cmd);
  617.         }
  618.     }
  619.     }
  620.     return inLine ? ObjTrue : ObjFalse;
  621. #else
  622.     return ObjFalse;
  623. #endif
  624. }
  625.  
  626.  
  627. static ObjPtr DrawScreenLine(line)
  628. ObjPtr line;
  629. /*Draws a line*/
  630. {
  631. #ifdef GRAPHICS
  632.     real startPoint[2], endPoint[2];
  633.     ObjPtr var;
  634.     int shadow, arrowHead;
  635.     real width;
  636.     real arrowParams[4][2];
  637.  
  638.     var = GetFixedArrayVar("DrawScreenLine", line, STARTPOINT, 1, 2L);
  639.     if (!var)
  640.     {
  641.     return ObjFalse;
  642.     }
  643.     Array2CArray(startPoint, var);
  644.  
  645.     var = GetFixedArrayVar("DrawScreenLine", line, ENDPOINT, 1, 2L);
  646.     if (!var)
  647.     {
  648.     return ObjFalse;
  649.     }
  650.     Array2CArray(endPoint, var);
  651.  
  652.     var = GetIntVar("DrawScreenLine", line, SHADOW);
  653.     if (var)
  654.     {
  655.     shadow = GetInt(var);
  656.     }
  657.     else
  658.     {
  659.     shadow = SH_NONE;
  660.     }
  661.  
  662.     var = GetIntVar("DrawScreenLine", line, ARROWHEAD);
  663.     if (var)
  664.     {
  665.     arrowHead = GetInt(var);
  666.     }
  667.     else
  668.     {
  669.     arrowHead = AH_NO_ARROW;
  670.     }
  671.  
  672.     var = GetRealVar("DrawScreenLine", line, LINEWIDTH);
  673.     if (var)
  674.     {
  675.     width = GetReal(var);
  676.     }
  677.     else
  678.     {
  679.     width = 1.0;
  680.     }
  681.  
  682.     arrowParams[0][0] = 0.0;
  683.     arrowParams[0][1] = 0.5;
  684.  
  685.     arrowParams[1][0] = -2.2;
  686.     arrowParams[1][1] = 0.5;
  687.  
  688.     arrowParams[2][0] = -4.25;
  689.     arrowParams[2][1] = 2.0;
  690.  
  691.     arrowParams[3][0] = -3.5;
  692.     arrowParams[3][1] = 2.0;
  693.  
  694.     /*Draw shadow if need be*/
  695.     if (shadow == SH_NONE)
  696.     {
  697.     }
  698.     else if (shadow == SH_BLACK)
  699.     {
  700.     /*Solid black shadow*/
  701.     SetUIColor(UIBLACK);
  702.     DrawSpacePanelLine(startPoint[0] + LINE_SHADOW, startPoint[1] - LINE_SHADOW,
  703.         endPoint[0] + LINE_SHADOW, endPoint[1] - LINE_SHADOW,
  704.         width, arrowHead, arrowParams);
  705.     }
  706.     else if ((shadow == SH_ALPHA) && rgbp && hasTransparency)
  707.     {
  708.     /*50% alpha black shadow*/
  709.     float cv[4];
  710.  
  711.     blendfunction(BF_SA, BF_MSA);
  712.     cv[0] = cv[1] = cv[2] = 0.0;
  713.     cv[3] = 0.5;
  714.     c4f(cv);
  715.     DrawSpacePanelLine(startPoint[0] + LINE_SHADOW, startPoint[1] - LINE_SHADOW,
  716.         endPoint[0] + LINE_SHADOW, endPoint[1] - LINE_SHADOW,
  717.         width, arrowHead, arrowParams);
  718.     blendfunction(BF_ONE, BF_ZERO);
  719.     }
  720.     else
  721.     {
  722.     /*Dithered shadow or fallback if no alpha*/
  723.     SetUIColor(UIBLACK);
  724.     BeginTranslucent();
  725.     DrawSpacePanelLine(startPoint[0] + LINE_SHADOW, startPoint[1] - LINE_SHADOW,
  726.         endPoint[0] + LINE_SHADOW, endPoint[1] - LINE_SHADOW,
  727.         width, arrowHead, arrowParams);
  728.     EndTranslucent();
  729.     }
  730.  
  731.     /*Draw line*/
  732.     var = GetVar(line, COLOR);
  733.     if (var)
  734.     {
  735.     SetObjectColor(var);
  736.     }
  737.     else
  738.     {
  739.     return ObjFalse;
  740.     }
  741.  
  742.     DrawSpacePanelLine(startPoint[0], startPoint[1], endPoint[0], endPoint[1],
  743.     width, arrowHead, arrowParams);
  744.  
  745.     /*Draw Handles*/
  746.     if (IsSelected(line))
  747.     {
  748.     DrawHandle((int) startPoint[0], (int) startPoint[1]);
  749.     DrawHandle((int) endPoint[0], (int) endPoint[1]);
  750.     }
  751. #endif
  752.     return ObjTrue;
  753. }
  754.  
  755. static ObjPtr DrawRectangle(rectangle)
  756. ObjPtr rectangle;
  757. /*Draws a rectangle*/
  758. {
  759. #ifdef GRAPHICS
  760.     int left, right, bottom, top;
  761.     int l, r, b, t;
  762.     ObjPtr cvar, background, var;
  763.     int shadow;
  764.     real width;
  765.  
  766.     Get2DIntBounds(rectangle, &left, &right, &bottom, &top);
  767.  
  768.     /*Get shadow*/
  769.     var = GetVar(rectangle, SHADOW);
  770.     if (var)
  771.     {
  772.     shadow = GetInt(var);
  773.     }
  774.     else
  775.     {
  776.     shadow = SH_NONE;
  777.     }
  778.  
  779.     l = left + HANDLESIZE / 2;
  780.     r = right - HANDLESIZE / 2;
  781.     t = top - HANDLESIZE / 2;
  782.     b = bottom + HANDLESIZE / 2;
  783.  
  784.     /*Draw shadow if need be*/
  785.     if (shadow == SH_NONE)
  786.     {
  787.     }
  788.     else if (shadow == SH_BLACK)
  789.     {
  790.     /*Solid black shadow*/
  791.     FillUIRect(r, r + RECT_SHADOW, b - RECT_SHADOW, t - RECT_SHADOW, UIBLACK);
  792.     FillUIRect(l + RECT_SHADOW, r, b - RECT_SHADOW, b, UIBLACK);
  793.     }
  794.     else if ((shadow == SH_ALPHA) && rgbp && hasTransparency)
  795.     {
  796.     /*50% alpha black shadow*/
  797.     float cv[4];
  798.  
  799.     blendfunction(BF_SA, BF_MSA);
  800.     cv[0] = cv[1] = cv[2] = 0.0;
  801.     cv[3] = 0.5;
  802.     c4f(cv);
  803.     FillRect(r, r + RECT_SHADOW, b - RECT_SHADOW, t - RECT_SHADOW);
  804.     FillRect(l + RECT_SHADOW, r, b - RECT_SHADOW, b);
  805.     blendfunction(BF_ONE, BF_ZERO);
  806.     }
  807.     else
  808.     {
  809.     /*Dithered shadow or fallback if no alpha*/
  810.     FillUIGauzeRect(r, r + RECT_SHADOW, b - RECT_SHADOW, t - RECT_SHADOW, UIBLACK);
  811.     FillUIGauzeRect(l + RECT_SHADOW, r, b - RECT_SHADOW, b, UIBLACK);
  812.     }
  813.  
  814.     /*Draw background*/
  815.     background = GetVar(rectangle, BACKGROUND);
  816.     if (background)
  817.     {
  818.     SetObjectColor(background);
  819.     FillRect(l, r, b, t);
  820.     }
  821.  
  822.     /*Draw border*/
  823.     cvar = GetVar(rectangle, COLOR);
  824.     if (cvar)
  825.     {
  826.     SetObjectColor(cvar);
  827.     }
  828.     else
  829.     {
  830.     return ObjFalse;
  831.     }
  832.  
  833.     var = GetRealVar("DrawRectangle", rectangle, LINEWIDTH);
  834.     if (var)
  835.     {
  836.     width = GetReal(var);
  837.     }
  838.     else
  839.     {
  840.     width = 2.0;
  841.     }
  842.     r += 1;
  843.     t += 1;
  844.  
  845.     if (GetPredicate(rectangle, BEVELED))
  846.     {
  847.     float clr[3];
  848.  
  849.     clr[0] = ((real *) ELEMENTS(cvar))[0];
  850.     clr[1] = ((real *) ELEMENTS(cvar))[1];
  851.     clr[2] = ((real *) ELEMENTS(cvar))[2];
  852.  
  853.     /*Draw top edge*/
  854.     if (!overDraw)
  855.     {
  856.         RGBC(clr);
  857.     }
  858.     FillIntQuad(l, t, l + width, t - width,
  859.              r - width, t - width, r, t);
  860.  
  861.     /*Draw left edge*/
  862.     clr[0] *= 0.75;
  863.     clr[1] *= 0.75;
  864.     clr[2] *= 0.75;
  865.     if (!overDraw)
  866.     {
  867.         RGBC(clr);
  868.     }
  869.     FillIntQuad(l, t, l, b,
  870.              l + width, b + width, l + width, t - width);
  871.  
  872.     /*Draw right edge*/
  873.     clr[0] *= 0.333;
  874.     clr[1] *= 0.333;
  875.     clr[2] *= 0.333;
  876.     if (!overDraw)
  877.     {
  878.         RGBC(clr);
  879.     }
  880.     FillIntQuad(r - width, t - width, r - width, b + width,
  881.              r, b, r, t);
  882.  
  883.     /*Draw bottom edge*/
  884.     clr[0] *= 0.5;
  885.     clr[1] *= 0.5;
  886.     clr[2] *= 0.5;
  887.     if (!overDraw)
  888.     {
  889.         RGBC(clr);
  890.     }
  891.     FillIntQuad(l, b, r, b,
  892.                  r - width, b + width, l + width, b + width);
  893.     }
  894.     else
  895.     {
  896.     FrameRealWideRect((real) l, (real) r, (real) b, (real) t, width);
  897.     }
  898.  
  899.     if (IsSelected(rectangle))
  900.     {
  901.     /*Thanks for the code, Jim.*/
  902.     int horCent = (left + right)/2;
  903.     int vertCent = (bottom + top)/2;
  904.  
  905.     /* Now draw the handles */
  906.  
  907.     /* center of sides */
  908.     DrawHandle(left + HANDLESIZE / 2, vertCent);
  909.     DrawHandle(right - HANDLESIZE / 2, vertCent); 
  910.  
  911.     /* top edge */
  912.     DrawHandle(horCent, top - HANDLESIZE / 2);
  913.     DrawHandle(left + HANDLESIZE / 2, top - HANDLESIZE / 2);
  914.     DrawHandle(right - HANDLESIZE / 2, top - HANDLESIZE / 2);
  915.  
  916.  
  917.     /* bottom edge */
  918.     DrawHandle(horCent, bottom + HANDLESIZE / 2);
  919.     DrawHandle(left + HANDLESIZE / 2, bottom + HANDLESIZE / 2);
  920.     DrawHandle(right - HANDLESIZE / 2, bottom + HANDLESIZE / 2);
  921.     }
  922. #endif
  923.     return ObjTrue;
  924. }
  925.  
  926. static ObjPtr ShowRectangleControls(display, windowName)
  927. ObjPtr display;
  928. char *windowName;
  929. /*Makes a new control window to control a rectangle*/
  930. {
  931.     WinInfoPtr controlWindow;
  932.     ObjPtr var;
  933.     ObjPtr panel;
  934.     ObjPtr corral;
  935.     ObjPtr contents;
  936.     WinInfoPtr dialogExists;
  937.     int mid;
  938.  
  939.     dialogExists = DialogExists((WinInfoPtr) display, NewString("Controls"));
  940.     controlWindow = GetDialog((WinInfoPtr) display, NewString("Controls"), windowName, 
  941.     RCWINWIDTH, RCWINHEIGHT, RCWINWIDTH,
  942.     RCWINHEIGHT, WINUI + WINFIXEDSIZE);
  943.     
  944.     if (!dialogExists)
  945.     {
  946.     long info;
  947.     ObjPtr value;
  948.     ObjPtr scale;    
  949.     ObjPtr checkBox, icon, name, colorBar, titleBox, textBox, button;
  950.     ObjPtr colorWheel, slider, radioGroup;
  951.     int left, right, bottom, top, center;
  952.  
  953.     SetVar((ObjPtr) controlWindow, REPOBJ, display);
  954.  
  955.     /*Set help string*/
  956.     SetVar((ObjPtr) controlWindow, HELPSTRING, NewString("This window \
  957. shows controls for a rectangle.  For information about any of the controls \
  958. in the window, use Help In Context on the control.\n"));
  959.  
  960.     /*Add in a panel*/
  961.     panel = NewPanel(greyPanelClass, 0, RCWINWIDTH, 0, RCWINHEIGHT);
  962.     if (!panel)
  963.     {
  964.         return NULLOBJ;
  965.     }
  966.     contents = GetVar((ObjPtr) controlWindow, CONTENTS);
  967.     PrefixList(contents, panel);
  968.     SetVar(panel, PARENT, (ObjPtr) controlWindow);
  969.  
  970.     contents = GetVar(panel, CONTENTS);
  971.  
  972.     /*Add in the group of controls for Border*/
  973.     left = MINORBORDER;
  974.     top = RCWINHEIGHT - MINORBORDER;
  975.     right = RCWINWIDTH - MINORBORDER;
  976.     center = (right + left) / 2;
  977.     right = center - MINORBORDER / 2;
  978.     bottom = MINORBORDER;
  979.     
  980.     titleBox = NewTitleBox(left, right,
  981.             /*top - TITLEBOXTOP - 3 * MINORBORDER - COLORWHEELWIDTH
  982.                 - CHECKBOXHEIGHT - TEXTBOXHEIGHT - TEXTBOXSEP,*/
  983.             bottom,
  984.             top, "Border");
  985.     SetVar(titleBox, PARENT, panel);
  986.     PrefixList(contents, titleBox);
  987.     left += MINORBORDER;
  988.     right  -= MINORBORDER;
  989.     top -= TITLEBOXTOP + MINORBORDER;
  990.  
  991.     /*Make the color wheel*/
  992.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  993.             top - COLORWHEELWIDTH, top, "Border Color");
  994.     
  995.     SetVar(colorWheel, PARENT, panel);
  996.     PrefixList(contents, colorWheel);
  997.     AssocColorControlWithVar(colorWheel, display, COLOR); 
  998.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  999. hue and saturation of the color used to draw the border of the rectangle.  \
  1000. The final color is a combination of this hue and saturation and the value, or brightness, \
  1001. given by the Value slider."));
  1002.     
  1003.     /*Make the text box below*/
  1004.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  1005.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1006.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1007.             PLAIN, "Border Color Label", "Color");
  1008.     SetVar(textBox, PARENT, panel);
  1009.     PrefixList(contents, textBox);
  1010.     SetTextAlign(textBox, CENTERALIGN);
  1011.  
  1012.     /*Make the brightness slider*/
  1013.     slider = NewSlider(right - SLIDERWIDTH, right, 
  1014.                top - COLORWHEELWIDTH, top,
  1015.                PLAIN, "Border Color Value");
  1016.     SetVar(slider, PARENT, panel);
  1017.     PrefixList(contents, slider);
  1018.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  1019.     AssocBrightnessControlWithVar(slider, display, COLOR);
  1020.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  1021. value, or brightness, of the color used to draw the text and lines in the palette legend.  \
  1022. The final color is a combination of this value and the hue and saturation \
  1023. given by the Color color wheel."));
  1024.  
  1025.     /*Make the text box below*/
  1026.     textBox = NewTextBox(right - SLIDERWIDTH - MAJORBORDER, right + MAJORBORDER,
  1027.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1028.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1029.             PLAIN, "Text Value Label", "Value");
  1030.     SetVar(textBox, PARENT, panel);
  1031.     PrefixList(contents, textBox);
  1032.     SetTextAlign(textBox, CENTERALIGN);
  1033.     top = top - COLORWHEELWIDTH - TEXTBOXSEP - MINORBORDER - TEXTBOXHEIGHT;
  1034.  
  1035.     /*Make group of controls for border width*/
  1036.     left = MINORBORDER;
  1037.     bottom = MINORBORDER;
  1038.     right = RCWINWIDTH - MINORBORDER;
  1039.     center = (right + left) / 2;
  1040.     right = center - MINORBORDER / 2;
  1041.  
  1042.     left += MINORBORDER;    
  1043.     right -= MINORBORDER;
  1044.  
  1045.     /*Make the border width slider*/
  1046.     top -= SCALESLOP;
  1047.     slider = TemplateSlider(RectangleTemplate, "Width Slider", SCALE);
  1048.     PrefixList(contents, slider);
  1049.     SetVar(slider, PARENT, panel);
  1050.  
  1051.     scale = TemplateScale(RectangleTemplate, "Width Scale", SO_TOP, false);
  1052.     SetScaleStepPixels(scale, 10);
  1053.     PrefixList(contents, scale);
  1054.     SetVar(scale, PARENT, panel);
  1055.     LinkScale(scale, slider);
  1056.     var = GetVar(display, LINEWIDTH);
  1057.     if (!var)
  1058.     {
  1059.         SetVar(display, LINEWIDTH, NewReal(3.0));
  1060.     }
  1061.     SetSliderRange(slider, 10.0, 1.0, 1.0);
  1062.     SetSliderScale(slider, 2.0, 1.0, 0.0, "%g");
  1063.     AssocDirectControlWithVar(slider, display, LINEWIDTH);
  1064.     SetVar(slider, HELPSTRING, NewString("This slider controls the width of \
  1065. the rectangle border in screen pixels.  A width of 0 means no border."));
  1066.     top = top - SLIDERWIDTH - TEXTBOXSEP;
  1067.  
  1068.     /*Make a legend*/
  1069.     textBox = NewTextBox(left, right, top - TEXTBOXHEIGHT, top,
  1070.         0, "Border Width Legend", "Border Width");
  1071.     SetVar(textBox, PARENT, panel);
  1072.     PrefixList(contents, textBox);
  1073.     SetTextAlign(textBox, CENTERALIGN);    
  1074.     top = top - TEXTBOXHEIGHT - MINORBORDER;
  1075.  
  1076.     /*Make a slider readout*/
  1077.     mid = top - MAX(TEXTBOXHEIGHT, EDITBOXHEIGHT) / 2;
  1078.     textBox = NewTextBox(left, (left + right) / 2,
  1079.         mid - EDITBOXHEIGHT / 2, 
  1080.         mid + EDITBOXHEIGHT / 2,
  1081.         EDITABLE + WITH_PIT + ONE_LINE, "Width Slider Readout", "");
  1082.     SetVar(textBox, REPOBJ, display);
  1083.     SetVar(textBox, PARENT, panel);
  1084.     SetTextAlign(textBox, RIGHTALIGN);
  1085.     PrefixList(contents, textBox);
  1086.     SliderReadout(slider, textBox);
  1087.  
  1088.     /*And "pixels"*/
  1089.     textBox = NewTextBox((left + right) / 2 + MINORBORDER, right,
  1090.         mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 
  1091.         mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
  1092.         0, "Pixels Legend", "Pixels");
  1093.     SetVar(textBox, PARENT, panel);
  1094.     PrefixList(contents, textBox);
  1095.  
  1096.     /*And a "beveled" check box*/
  1097.     bottom += MINORBORDER;
  1098.     if (!GetVar(display, BEVELED))
  1099.     {
  1100.         SetVar(display, BEVELED, ObjFalse);
  1101.     }
  1102.     checkBox = NewCheckBox(left, right, 
  1103.         bottom, bottom + CHECKBOXHEIGHT,
  1104.         "Beveled", GetPredicate(display, BEVELED));
  1105.     PrefixList(contents, checkBox);
  1106.     SetVar(checkBox, PARENT, panel);
  1107.     AssocDirectControlWithVar(checkBox, display, BEVELED);
  1108.  
  1109.     /*Make the background controls*/
  1110.     top = RCWINHEIGHT - MINORBORDER;
  1111.     right = RCWINWIDTH - MINORBORDER;
  1112.     left = MINORBORDER;
  1113.     center = (right + left) / 2;
  1114.     left = center + MINORBORDER / 2;
  1115.     
  1116.     titleBox = NewTitleBox(left, right,
  1117.             top - TITLEBOXTOP - MINORBORDER - 2 * MINORBORDER - COLORWHEELWIDTH
  1118.                 - CHECKBOXHEIGHT - TEXTBOXHEIGHT - TEXTBOXSEP,
  1119.             top, "Interior");
  1120.     SetVar(titleBox, PARENT, panel);
  1121.     PrefixList(contents, titleBox);
  1122.     left += MINORBORDER;
  1123.     right -= MINORBORDER;
  1124.     top -= TITLEBOXTOP + MINORBORDER;
  1125.  
  1126.     /*Make the color wheel*/
  1127.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  1128.             top - COLORWHEELWIDTH, top, "Background Color");
  1129.     SetVar(colorWheel, PARENT, panel);
  1130.     SetVar(colorWheel, REPOBJ, display);
  1131.     PrefixList(contents, colorWheel);
  1132.     AssocColorControlWithVar(colorWheel, display, BACKGROUND);
  1133.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  1134. hue and saturation of the color used to draw the interior of the rectangle.  \
  1135. The final color is a combination of this hue and saturation and the value, or brightness, \
  1136. given by the Value slider."));
  1137.     
  1138.     /*Make the text box below*/
  1139.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  1140.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1141.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1142.             PLAIN, "Background Color Label", "Color");
  1143.     SetVar(textBox, PARENT, panel);
  1144.     PrefixList(contents, textBox);
  1145.     SetTextAlign(textBox, CENTERALIGN);
  1146.  
  1147.     /*Make the brightness slider*/
  1148.     slider = NewSlider(right - SLIDERWIDTH, right, 
  1149.                top - COLORWHEELWIDTH, top,
  1150.                PLAIN, "Background Value");
  1151.     SetVar(slider, PARENT, panel);
  1152.     PrefixList(contents, slider);
  1153.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  1154.     AssocBrightnessControlWithVar(slider, display, BACKGROUND);
  1155.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  1156. value, or brightness, of the color used to draw the interior of the rectangle.  \
  1157. The final color is a combination of this value and the hue and saturation \
  1158. given by the Color color wheel."));
  1159.  
  1160.     /*Make the text box below*/
  1161.     textBox = NewTextBox(right - SLIDERWIDTH - MAJORBORDER, right + MAJORBORDER,
  1162.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1163.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1164.             PLAIN, "Background Value Label", "Value");
  1165.     SetVar(textBox, PARENT, panel);
  1166.     PrefixList(contents, textBox);
  1167.     SetTextAlign(textBox, CENTERALIGN);
  1168.  
  1169.     /*Make the check box*/
  1170.     top -= COLORWHEELWIDTH + TEXTBOXSEP + TEXTBOXHEIGHT + MINORBORDER;
  1171.     checkBox = NewCheckBox(left, right, 
  1172.         top - CHECKBOXHEIGHT, top,
  1173.         "No Interior", false);
  1174.     SetVar(checkBox, PARENT, panel);
  1175.     PrefixList(contents, checkBox);
  1176.     AssocInhibitControlWithVar(checkBox, display, BACKGROUND, NewInt(UIBLACK));
  1177.     SetVar(checkBox, HELPSTRING, NewString("This checkbox controls whether \
  1178. the interior of the rectangle is shown.  If it is selected, no interior is shown, and the \
  1179. objects behind the rectangle can be seen."));
  1180.  
  1181.     /*Make group of controls for shadow*/
  1182.     left = MINORBORDER;
  1183.     bottom = MINORBORDER;
  1184.     top = bottom + 4 * CHECKBOXHEIGHT + 3 * CHECKBOXSPACING + 2 * MINORBORDER + TITLEBOXTOP;
  1185.     right = RCWINWIDTH - MINORBORDER;
  1186.     center = (right + left) / 2;
  1187.     left = center + MINORBORDER / 2;
  1188.  
  1189.     /*Make the title box*/
  1190.     titleBox = NewTitleBox(left, right,
  1191.             bottom, top, "Shadow");
  1192.     SetVar(titleBox, PARENT, panel);
  1193.     PrefixList(contents, titleBox);
  1194.     left += MINORBORDER;
  1195.     right  -= MINORBORDER;
  1196.     top -= TITLEBOXTOP + MINORBORDER;
  1197.  
  1198.     /*Set up the radio group*/
  1199.     radioGroup = NewRadioButtonGroup("Shadow Radio");
  1200.         SetVar(radioGroup, HELPSTRING,
  1201.        NewString("This is a group of radio buttons which control the shadow \
  1202. behing the rectangle.  For information on a particular shadow, use Help in Context on \
  1203. the desired button."));
  1204.     SetVar(radioGroup, PARENT, panel);
  1205.     PrefixList(contents, radioGroup);
  1206.     SetVar(radioGroup, HALTHELP, ObjTrue);
  1207.  
  1208.     /*Make the Plain button*/
  1209.     button = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "None");
  1210.     SetVar(button, HELPSTRING, 
  1211.         NewString("This button selects no shadow."));
  1212.     AddRadioButton(radioGroup, button);
  1213.     top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
  1214.  
  1215.     /*Make the Gray dithered button*/
  1216.     button = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Dithered Gray");
  1217.     SetVar(button, HELPSTRING, 
  1218.         NewString("This button selects a gray shadow.  The shadow will appear \
  1219. behind the rectangle at the lower right.\
  1220. The shadow is drawn in black with a 50% dither pattern, so it only partially \
  1221. obscures what is below.  As it uses the same dither pattern that \
  1222. translucent objects use, it will entirely obscure translucent objects.  \
  1223. Transparent objects will be partially obscured"));
  1224.     AddRadioButton(radioGroup, button);
  1225.     top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
  1226.  
  1227.     /*Make the Beveled button*/
  1228.     button = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Alpha Gray");
  1229.     SetVar(button, HELPSTRING, 
  1230.         NewString("This button selects a gray shadow.  The shadow will appear \
  1231. behind the rectangle at the lower right.\
  1232. The shadow is drawn in black using 50% alpha transparency, so it only partially \
  1233. obscures what is below.  This kind of gray shadow provides a better effect than \
  1234. dithered gray with translucent objects, but it will only work if the hardware \
  1235. supports alpha blending and the window is set to full color mode.  \
  1236. If not, this shadow behaves the same as the dithered gray shadow."));
  1237.     AddRadioButton(radioGroup, button);
  1238.     top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
  1239.  
  1240.     /*Make the Black shadow button*/
  1241.     button = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Black");
  1242.     SetVar(button, HELPSTRING, 
  1243.         NewString("This button selects a black shadow.  \
  1244. The shadow will appear behind the rectangle at the lower right.\
  1245. The shadow is drawn in solid black, so it entirely obscures what is below."));
  1246.     AddRadioButton(radioGroup, button);
  1247.     top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
  1248.  
  1249.     /*Set its value*/
  1250.     AssocDirectControlWithVar(radioGroup, display, SHADOW);
  1251.     }
  1252.     return (ObjPtr) controlWindow;
  1253. }
  1254.  
  1255. static ObjPtr ShowLineControls(display, windowName)
  1256. ObjPtr display;
  1257. char *windowName;
  1258. /*Makes a new control window to control a line*/
  1259. {
  1260.     WinInfoPtr controlWindow;
  1261.     ObjPtr var;
  1262.     ObjPtr panel;
  1263.     ObjPtr corral;
  1264.     ObjPtr contents;
  1265.     real rgb[3], hsv[3];
  1266.     WinInfoPtr dialogExists;
  1267.     ObjPtr scale;
  1268.  
  1269.     dialogExists = DialogExists((WinInfoPtr) display, NewString("Controls"));
  1270.     controlWindow = GetDialog((WinInfoPtr) display, NewString("Controls"), windowName, 
  1271.     LCWINWIDTH, LCWINHEIGHT, LCWINWIDTH,
  1272.     LCWINHEIGHT, WINUI + WINFIXEDSIZE);
  1273.     
  1274.     if (!dialogExists)
  1275.     {
  1276.     long info;
  1277.     ObjPtr value;
  1278.     
  1279.     ObjPtr checkBox, icon, name, colorBar, titleBox, textBox, button;
  1280.     ObjPtr colorWheel, slider, radioGroup;
  1281.     int left, right, bottom, top, center, arrowhead;
  1282.  
  1283.     SetVar((ObjPtr) controlWindow, REPOBJ, display);
  1284.  
  1285.     /*Set help string*/
  1286.     SetVar((ObjPtr) controlWindow, HELPSTRING, NewString("This window \
  1287. shows controls for a line.  For information about any of the controls \
  1288. in the window, use Help In Context on the control.\n"));
  1289.  
  1290.     /*Add in a panel*/
  1291.     panel = NewPanel(greyPanelClass, 0, LCWINWIDTH, 0, LCWINHEIGHT);
  1292.     if (!panel)
  1293.     {
  1294.         return NULLOBJ;
  1295.     }
  1296.     contents = GetVar((ObjPtr) controlWindow, CONTENTS);
  1297.     PrefixList(contents, panel);
  1298.     SetVar(panel, PARENT, (ObjPtr) controlWindow);
  1299.  
  1300.     contents = GetVar(panel, CONTENTS);
  1301.  
  1302.     /*Add in the group of controls for Line*/
  1303.     left = MINORBORDER;
  1304.     top = LCWINHEIGHT - MINORBORDER;
  1305.     right = LCWINWIDTH - MINORBORDER;
  1306.     center = (right + left) / 2;
  1307.     right = center - MINORBORDER / 2;
  1308.     bottom = MINORBORDER;
  1309.  
  1310.     titleBox = TemplateTitleBox(LineTemplate, "Line");
  1311.     SetVar(titleBox, PARENT, panel);
  1312.     PrefixList(contents, titleBox);
  1313.     left += MINORBORDER;
  1314.     right  -= MINORBORDER;
  1315.     top -= TITLEBOXTOP + MINORBORDER;
  1316.  
  1317.     /*Make the color wheel*/
  1318.     colorWheel = NewColorWheel(left, left + COLORWHEELWIDTH,
  1319.             top - COLORWHEELWIDTH, top, "Line Color");
  1320.     SetVar(colorWheel, PARENT, panel);
  1321.     PrefixList(contents, colorWheel);
  1322.     AssocColorControlWithVar(colorWheel, display, COLOR);
  1323.     SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \
  1324. hue and saturation of the color used to draw the line.  \
  1325. The final color is a combination of this hue and saturation and the value, or brightness, \
  1326. given by the Value slider."));
  1327.     
  1328.     /*Make the text box below*/
  1329.     textBox = NewTextBox(left, left + COLORWHEELWIDTH,
  1330.             top - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT,
  1331.             top - COLORWHEELWIDTH - TEXTBOXSEP,
  1332.             PLAIN, "Line Color Label", "Color");
  1333.     SetVar(textBox, PARENT, panel);
  1334.     PrefixList(contents, textBox);
  1335.     SetTextAlign(textBox, CENTERALIGN);
  1336.  
  1337.     /*Make the brightness slider*/
  1338.     slider = NewSlider(right - SLIDERWIDTH, right, 
  1339.                top - COLORWHEELWIDTH, top,
  1340.                PLAIN, "Line Color Value");
  1341.     SetVar(slider, PARENT, panel);
  1342.     PrefixList(contents, slider);
  1343.     SetSliderRange(slider, 1.0, 0.0, 0.0);
  1344.     AssocBrightnessControlWithVar(slider, display, COLOR);
  1345.     SetVar(slider, HELPSTRING, NewString("This slider controls the \
  1346. value, or brightness, of the color used to draw the text and lines in the palette legend.  \
  1347. The final color is a combination of this value and the hue and saturation \
  1348. given by the Color color wheel."));
  1349.  
  1350.     /*Make the text box below*/
  1351.     textBox = TemplateTextBox(LineTemplate, "Text Value Label", 
  1352.             PLAIN, "Value");
  1353.     SetVar(textBox, PARENT, panel);
  1354.     PrefixList(contents, textBox);
  1355.     SetTextAlign(textBox, CENTERALIGN);
  1356.  
  1357.     /*Cross link the slider and color wheel*/
  1358.     SetVar(colorWheel, SLIDER, slider);
  1359.     SetVar(slider, COLORWHEEL, colorWheel);
  1360.  
  1361.     /*Make group of controls for line width*/
  1362.  
  1363.     /*Make the line width slider*/
  1364.     slider = TemplateSlider(LineTemplate, "Width Slider", SCALE);
  1365.     PrefixList(contents, slider);
  1366.     SetVar(slider, PARENT, panel);
  1367.  
  1368.     scale = TemplateScale(LineTemplate, "Width Scale", SO_TOP, false);
  1369.     SetScaleStepPixels(scale, 10);
  1370.     PrefixList(contents, scale);
  1371.     SetVar(scale, PARENT, panel);
  1372.     LinkScale(scale, slider);
  1373.  
  1374.     var = GetVar(display, LINEWIDTH);
  1375.     if (!var)
  1376.     {
  1377.         SetVar(display, LINEWIDTH, NewReal(3.0));
  1378.     }
  1379.     SetSliderRange(slider, 10.0, 1.0, 1.0);
  1380.     SetSliderScale(slider, 2.0, 1.0, 0.0, "%g");
  1381.     AssocDirectControlWithVar(slider, display, LINEWIDTH);
  1382.     SetVar(slider, HELPSTRING, NewString("This slider controls the width of \
  1383. the line in screen pixels."));
  1384.  
  1385.     /*Make a legend*/
  1386.     textBox = TemplateTextBox(LineTemplate, "Line Width Legend", 0, "Line Width");
  1387.     SetVar(textBox, PARENT, panel);
  1388.     PrefixList(contents, textBox);
  1389.     SetTextAlign(textBox, CENTERALIGN);    
  1390.     SetVar(textBox, HELPSTRING, NewString("This text box controls the width of \
  1391. the line in screen pixels."));
  1392.  
  1393.     /*Make a slider readout*/
  1394.     textBox = TemplateTextBox(LineTemplate, "Width Slider Readout", EDITABLE + WITH_PIT + ONE_LINE, "");
  1395.     SetVar(textBox, REPOBJ, display);
  1396.     SetVar(textBox, PARENT, panel);
  1397.     SetTextAlign(textBox, RIGHTALIGN);
  1398.     PrefixList(contents, textBox);
  1399.     SliderReadout(slider, textBox);
  1400.  
  1401.     /*And "pixels"*/
  1402.     textBox = TemplateTextBox(LineTemplate, "Pixels Legend", 0, "Pixels");
  1403.     SetVar(textBox, PARENT, panel);
  1404.     PrefixList(contents, textBox);
  1405.  
  1406.     /*Make group of controls for arrow*/
  1407.  
  1408.     /*Get arrowhead for check boxes later
  1409.     var = GetVar(display, ARROWHEAD);
  1410.     if (var)
  1411.     {
  1412.         arrowhead = GetInt(var);
  1413.     }
  1414.     else
  1415.     {
  1416.         arrowhead = AH_NOARROW;
  1417.         SetVar(display, ARROWHEAD, NewInt(arrowhead));
  1418.     }
  1419.  
  1420.     /*Make the title box*/
  1421.     titleBox = TemplateTitleBox(LineTemplate, "Arrowhead");
  1422.     SetVar(titleBox, PARENT, panel);
  1423.     PrefixList(contents, titleBox);
  1424.  
  1425.     /*Make the two check boxes for arrowheads*/
  1426.     checkBox = TemplateCheckBox(LineTemplate, "At Start", (arrowhead & AH_AT_START) ? 1 : 0);
  1427.     PrefixList(contents, checkBox);
  1428.     SetVar(checkBox, PARENT, panel);
  1429.     AssocFlagControlWithVar(checkBox, display, ARROWHEAD, AH_AT_START);
  1430.     SetVar(checkBox, HELPSTRING, NewString("If this box is checked, an arrowhead \
  1431. will appear at the start of the line.  If both the At Start and At End boxes are \
  1432. checked, arrowheads will appear at both ends."));
  1433.  
  1434.     checkBox = TemplateCheckBox(LineTemplate, "At End", (arrowhead & AH_AT_END) ? 1 : 0);
  1435.     PrefixList(contents, checkBox);
  1436.     SetVar(checkBox, PARENT, panel);
  1437.     AssocFlagControlWithVar(checkBox, display, ARROWHEAD, AH_AT_END);
  1438.     SetVar(checkBox, HELPSTRING, NewString("If this box is checked, an arrowhead \
  1439. will appear at the end of the line.  If both the At Start and At End boxes are \
  1440. checked, arrowheads will appear at both ends."));
  1441.  
  1442.     /*Make group of controls for shadow*/
  1443.  
  1444.     /*Make the title box*/
  1445.     titleBox = TemplateTitleBox(LineTemplate, "Shadow");
  1446.     SetVar(titleBox, PARENT, panel);
  1447.     PrefixList(contents, titleBox);
  1448.  
  1449.     /*Set up the radio group*/
  1450.     radioGroup = NewRadioButtonGroup("Shadow Radio");
  1451.         SetVar(radioGroup, HELPSTRING,
  1452.        NewString("This is a group of radio buttons which control the shadow \
  1453. behing the line.  For information on a particular shadow, use Help in Context on \
  1454. the desired button."));
  1455.     SetVar(radioGroup, PARENT, panel);
  1456.     PrefixList(contents, radioGroup);
  1457.     SetVar(radioGroup, HALTHELP, ObjTrue);
  1458.  
  1459.     /*Make the Plain button*/
  1460.     button = TemplateRadioButton(LineTemplate, "None");
  1461.     SetVar(button, HELPSTRING, 
  1462.         NewString("This button selects no shadow."));
  1463.     AddRadioButton(radioGroup, button);
  1464.     
  1465.     /*Make the Gray dithered button*/
  1466.     button = TemplateRadioButton(LineTemplate, "Dithered Gray");
  1467.     SetVar(button, HELPSTRING, 
  1468.         NewString("This button selects a gray shadow.  The shadow will appear \
  1469. behind the line at the lower right.\
  1470. The shadow is drawn in black with a 50% dither pattern, so it only partially \
  1471. obscures what is below.  As it uses the same dither pattern that \
  1472. translucent objects use, it will entirely obscure translucent objects.  \
  1473. Transparent objects will be partially obscured"));
  1474.     AddRadioButton(radioGroup, button);
  1475.  
  1476.     /*Make the Beveled button*/
  1477.     button = TemplateRadioButton(LineTemplate, "Alpha Gray");
  1478.     SetVar(button, HELPSTRING, 
  1479.         NewString("This button selects a gray shadow.  The shadow will appear \
  1480. behind the line at the lower right.\
  1481. The shadow is drawn in black using 50% alpha transparency, so it only partially \
  1482. obscures what is below.  This kind of gray shadow provides a better effect than \
  1483. dithered gray with translucent objects, but it will only work if the hardware \
  1484. supports alpha blending and the window is set to full color mode.  \
  1485. If not, this shadow behaves the same as the dithered gray shadow."));
  1486.     AddRadioButton(radioGroup, button);
  1487.  
  1488.     /*Make the Black shadow button*/
  1489.     button = TemplateRadioButton(LineTemplate, "Black");
  1490.     SetVar(button, HELPSTRING, 
  1491.         NewString("This button selects a black shadow.  \
  1492. The shadow will appear behind the line at the lower right.\
  1493. The shadow is drawn in solid black, so it entirely obscures what is below."));
  1494.     AddRadioButton(radioGroup, button);
  1495.  
  1496.     /*Set its value*/
  1497.     AssocDirectControlWithVar(radioGroup, display, SHADOW);
  1498.     }
  1499.     return (ObjPtr) controlWindow;
  1500. }
  1501.  
  1502. ObjPtr PushDrawingToBottom(drawing)
  1503. ObjPtr drawing;
  1504. /*Pushes a drawing to the bottom*/
  1505. {
  1506.     ObjPtr parent, contents;
  1507.  
  1508.     /*Get the parent*/
  1509.     parent = GetObjectVar("PushDrawingToBottom", drawing, PARENT);
  1510.     if (!parent)
  1511.     {
  1512.     return ObjFalse;
  1513.     }
  1514.  
  1515.     /*And parent's contents*/
  1516.     contents = GetListVar("PushDrawingToBottom", parent, CONTENTS);
  1517.     if (!contents)
  1518.     {
  1519.     return ObjFalse;
  1520.     }
  1521.  
  1522.     /*Delete and replace it*/
  1523.     DeleteFromList(contents, drawing);
  1524.     PostfixList(contents, drawing);
  1525.     ImInvalid(parent);
  1526.  
  1527.     return ObjTrue;
  1528. }
  1529.  
  1530. ObjPtr BringDrawingToTop(drawing)
  1531. ObjPtr drawing;
  1532. /*Brings a drawing to the top*/
  1533. {
  1534.     ObjPtr parent, contents;
  1535.  
  1536.     /*Get the parent*/
  1537.     parent = GetObjectVar("BringDrawingToTop", drawing, PARENT);
  1538.     if (!parent)
  1539.     {
  1540.     return ObjFalse;
  1541.     }
  1542.  
  1543.     /*And parent's contents*/
  1544.     contents = GetListVar("BringDrawingToTop", parent, CONTENTS);
  1545.     if (!contents)
  1546.     {
  1547.     return ObjFalse;
  1548.     }
  1549.  
  1550.     /*Delete and replace it*/
  1551.     DeleteFromList(contents, drawing);
  1552.     PrefixList(contents, drawing);
  1553.     ImInvalid(parent);
  1554.  
  1555.     return ObjTrue;
  1556. }
  1557.  
  1558. ObjPtr MoveDrawingToBackPanel(drawing)
  1559. ObjPtr drawing;
  1560. /*Moves a drawing to the (top of the) back panel*/
  1561. {
  1562.     ObjPtr parent, contents, space, newPanel, newContents;
  1563.  
  1564.     /*Get the parent*/
  1565.     parent = GetObjectVar("MoveDrawingToBackPanel", drawing, PARENT);
  1566.     if (!parent)
  1567.     {
  1568.     return ObjFalse;
  1569.     }
  1570.  
  1571.     /*And parent's contents*/
  1572.     contents = GetListVar("MoveDrawingToBackPanel", parent, CONTENTS);
  1573.     if (!contents)
  1574.     {
  1575.     return ObjFalse;
  1576.     }
  1577.  
  1578.     /*And the space*/
  1579.     space = GetObjectVar("MoveDrawingToBackPanel", parent, SPACE);
  1580.     if (!space)
  1581.     {
  1582.     return ObjFalse;
  1583.     }
  1584.  
  1585.     /*And it's back panel*/
  1586.     newPanel = GetObjectVar("MoveDrawingToBackPanel", space, BACKPANEL);
  1587.     if (!newPanel)
  1588.     {
  1589.     return ObjFalse;
  1590.     }
  1591.  
  1592.     /*And the panel's contents*/
  1593.     newContents = GetListVar("MoveDrawingToBackPanel", newPanel, CONTENTS);
  1594.     if (!newContents)
  1595.     {
  1596.     return ObjFalse;
  1597.     }
  1598.  
  1599.  
  1600.     /*Delete the drawing*/
  1601.     ImInvalid(drawing);
  1602.     DeleteFromList(contents, drawing);
  1603.  
  1604.     /*Add it to the new contents*/
  1605.     PrefixList(newContents, drawing);
  1606.     SetVar(drawing, PARENT, newPanel);
  1607.     ImInvalid(drawing);
  1608.  
  1609.     return ObjTrue;
  1610. }
  1611.  
  1612. ObjPtr MoveDrawingToFrontPanel(drawing)
  1613. ObjPtr drawing;
  1614. /*Moves a drawing to the (top of the) front panel*/
  1615. {
  1616.     ObjPtr parent, contents, space, newPanel, newContents;
  1617.  
  1618.     /*Get the parent*/
  1619.     parent = GetObjectVar("MoveDrawingToBackPanel", drawing, PARENT);
  1620.     if (!parent)
  1621.     {
  1622.     return ObjFalse;
  1623.     }
  1624.  
  1625.     /*And parent's contents*/
  1626.     contents = GetListVar("MoveDrawingToBackPanel", parent, CONTENTS);
  1627.     if (!contents)
  1628.     {
  1629.     return ObjFalse;
  1630.     }
  1631.  
  1632.     /*And the space*/
  1633.     space = GetObjectVar("MoveDrawingToBackPanel", parent, SPACE);
  1634.     if (!space)
  1635.     {
  1636.     return ObjFalse;
  1637.     }
  1638.  
  1639.     /*And it's front panel*/
  1640.     newPanel = GetObjectVar("MoveDrawingToBackPanel", space, FRONTPANEL);
  1641.     if (!newPanel)
  1642.     {
  1643.     return ObjFalse;
  1644.     }
  1645.  
  1646.     /*And the panel's contents*/
  1647.     newContents = GetListVar("MoveDrawingToBackPanel", newPanel, CONTENTS);
  1648.     if (!newContents)
  1649.     {
  1650.     return ObjFalse;
  1651.     }
  1652.  
  1653.  
  1654.     /*Delete the drawing*/
  1655.     ImInvalid(drawing);
  1656.     DeleteFromList(contents, drawing);
  1657.  
  1658.     /*Add it to the new contents*/
  1659.     PrefixList(newContents, drawing);
  1660.     SetVar(drawing, PARENT, newPanel);
  1661.     ImInvalid(drawing);
  1662.  
  1663.     return ObjTrue;
  1664. }
  1665.  
  1666. ObjPtr CloneAnnotation(drawing)
  1667. ObjPtr drawing;
  1668. /*Clones a drawing*/
  1669. {
  1670.     ObjPtr retVal;
  1671.  
  1672.     retVal = Clone(drawing);
  1673.     sprintf(tempStr, "Annotation %d", nAnnot++);
  1674.     SetVar(retVal, NAME, NewString(tempStr));
  1675.     return retVal;
  1676. }
  1677.  
  1678. ObjPtr CloneTimeReadout(drawing)
  1679. ObjPtr drawing;
  1680. /*Clones a drawing*/
  1681. {
  1682.     ObjPtr retVal;
  1683.  
  1684.     retVal = Clone(drawing);
  1685.     sprintf(tempStr, "Time Readout %d", nTimeReadout++);
  1686.     SetVar(retVal, NAME, NewString(tempStr));
  1687.     return retVal;
  1688. }
  1689.  
  1690. ObjPtr CloneLine(drawing)
  1691. ObjPtr drawing;
  1692. /*Clones a drawing*/
  1693. {
  1694.     ObjPtr retVal;
  1695.  
  1696.     retVal = Clone(drawing);
  1697.     sprintf(tempStr, "Line %d", nLine++);
  1698.     SetVar(retVal, NAME, NewString(tempStr));
  1699.     return retVal;
  1700. }
  1701.  
  1702. ObjPtr CloneRectangle(drawing)
  1703. ObjPtr drawing;
  1704. /*Clones a drawing*/
  1705. {
  1706.     ObjPtr retVal;
  1707.  
  1708.     retVal = Clone(drawing);
  1709.     sprintf(tempStr, "Rectangle %d", nRect++);
  1710.     SetVar(retVal, NAME, NewString(tempStr));
  1711.     return retVal;
  1712. }
  1713.  
  1714. void InitDrawings()
  1715. /*Initializes all the drawings*/
  1716. {
  1717.     ObjPtr color;
  1718.     ObjPtr list;
  1719.  
  1720.     drawingClass = NewObject(controlClass, 0L);
  1721.     AddToReferenceList(drawingClass);
  1722.     SetMethod(drawingClass, SELECT, SelectDrawing);
  1723.     SetMethod(drawingClass, DELETE, DeleteObject);
  1724.     SetMethod(drawingClass, CLONE, Clone);
  1725.     SetMethod(drawingClass, DUPLICATE, DuplicateDrawing);
  1726.     SetMethod(drawingClass, PUSHTOBOTTOM, PushDrawingToBottom);
  1727.     SetMethod(drawingClass, BRINGTOTOP, BringDrawingToTop);
  1728.     SetMethod(drawingClass, MOVETOBACKPANEL, MoveDrawingToBackPanel);
  1729.     SetMethod(drawingClass, MOVETOFRONTPANEL, MoveDrawingToFrontPanel);
  1730.     SetMethod(drawingClass, PICKUP, (FuncTyp) 0);
  1731.  
  1732.     rectangleClass = NewObject(drawingClass, 0L);
  1733.     AddToReferenceList(rectangleClass);
  1734.     color = NewRealArray(1, 3L);
  1735.     ((real *) ELEMENTS(color))[0] = 1.0;
  1736.     ((real *) ELEMENTS(color))[1] = 1.0;
  1737.     ((real *) ELEMENTS(color))[2] = 1.0;
  1738.     SetVar(rectangleClass, COLOR, color);
  1739.     SetVar(rectangleClass, LINEWIDTH, NewReal(3.0));
  1740.     SetVar(rectangleClass, SHADOW, NewInt(SH_NONE));
  1741.     SetMethod(rectangleClass, DRAW, DrawRectangle);
  1742.     SetMethod(rectangleClass, PRESS, PressRectangle);
  1743.     SetMethod(rectangleClass, NEWCTLWINDOW, ShowRectangleControls);
  1744.     SetMethod(rectangleClass, DELETEICON, DeleteSpacePanelDrawing);
  1745.     SetVar(rectangleClass, TYPESTRING, NewString("rectangle"));
  1746.     SetVar(rectangleClass, HELPSTRING,
  1747.     NewString("The rectangle is a graphical object that can be used on \
  1748. space panels to dress up a visualization.  To change the size or location \
  1749. of this rectangle, first click anywhere on the border of the rectangle to select it. A frame will \
  1750. appear around the rectangle with eight small handles. Drag any of the handles to change \
  1751. the size of the rectangle. Drag the frame itself to reposition the rectangle.  You can \
  1752. change the style and color from within the rectangle's control panel."));
  1753.     list = NewList();
  1754.     PrefixList(list, NewSymbol(BOUNDS));
  1755.     SetVar(rectangleClass, SNAPVARS, list);
  1756.  
  1757.     lineClass = NewObject(drawingClass, 0L);
  1758.     AddToReferenceList(lineClass);
  1759.     color = NewRealArray(1, 3L);
  1760.     ((real *) ELEMENTS(color))[0] = 1.0;
  1761.     ((real *) ELEMENTS(color))[1] = 1.0;
  1762.     ((real *) ELEMENTS(color))[2] = 1.0;
  1763.     SetVar(lineClass, COLOR, color);
  1764.     SetVar(lineClass, LINEWIDTH, NewReal(5.0));
  1765.     SetVar(lineClass, SHADOW, NewInt(SH_NONE));
  1766.     SetVar(lineClass, ARROWHEAD, NewInt(AH_NO_ARROW));
  1767.     SetVar(lineClass, TYPESTRING, NewString("line"));
  1768.     SetVar(lineClass, HELPSTRING,
  1769.     NewString("The line is a graphical object that can be used on \
  1770. space panels to dress up a visualization.  To change the size or location \
  1771. of this line, first click anywhere on the line to select it.  Two small handles \
  1772. will appear, on at each end of the line.  Drag a handle to change the endpoint.  \
  1773. To move the entire line, click on the line and drag."));
  1774.     SetMethod(lineClass, DRAW, DrawScreenLine);
  1775.     SetMethod(lineClass, NEWCTLWINDOW, ShowLineControls);
  1776.     SetMethod(lineClass, PRESS, PressLine);
  1777.     SetMethod(lineClass, DELETEICON, DeleteSpacePanelDrawing);
  1778.     list = NewList();
  1779.     PrefixList(list, NewSymbol(BOUNDS));
  1780.     PrefixList(list, NewSymbol(STARTPOINT));
  1781.     PrefixList(list, NewSymbol(ENDPOINT));
  1782.     SetVar(lineClass, SNAPVARS, list);
  1783. }
  1784.  
  1785. void KillDrawings()
  1786. /*Kills all the drawings*/
  1787. {
  1788.     RemoveFromReferenceList(lineClass);
  1789.     RemoveFromReferenceList(rectangleClass);
  1790.     RemoveFromReferenceList(drawingClass);
  1791. }
  1792.